#!/bin/bash
# 批量提取所有OpenBMC库的ABI信息
# 功能：遍历所有.so文件，提取ABI数据到JSON格式

set -e

# 配置路径
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
LIBRARY_DIR="$PROJECT_ROOT/data/build/libraries"
OUTPUT_DIR="$PROJECT_ROOT/output/abi_data"
EXTRACTOR_SCRIPT="$PROJECT_ROOT/src/extractor/abi_extractor.py"

# 日志函数
log_info() {
    echo "[INFO] $(date '+%Y-%m-%d %H:%M:%S') - $*"
}

log_success() {
    echo "[SUCCESS] $(date '+%Y-%m-%d %H:%M:%S') - $*"
}

log_error() {
    echo "[ERROR] $(date '+%Y-%m-%d %H:%M:%S') - $*" >&2
}

# 检查必要工具
check_tools() {
    local missing_tools=()
    
    for tool in python3 nm readelf c++filt file; do
        if ! command -v "$tool" &>/dev/null; then
            missing_tools+=("$tool")
        fi
    done
    
    if [ ${#missing_tools[@]} -gt 0 ]; then
        log_error "缺少必要工具: ${missing_tools[*]}"
        log_error "请安装: sudo apt-get install binutils file"
        exit 1
    fi
    
    log_success "所有必要工具已就绪"
}

# 创建输出目录
prepare_output_dir() {
    mkdir -p "$OUTPUT_DIR"
    log_info "输出目录: $OUTPUT_DIR"
}

# 提取单个库的ABI
extract_library_abi() {
    local lib_file="$1"
    local lib_name=$(basename "$lib_file")
    local output_excel="$OUTPUT_DIR/${lib_name}.abi.xlsx"
    
    log_info "提取 $lib_name ..."
    
    if python3 "$EXTRACTOR_SCRIPT" \
        --library "$lib_file" \
        --output "$output_excel"; then
        log_success "✓ $lib_name -> ${lib_name}.abi.xlsx"
        return 0
    else
        log_error "✗ $lib_name 提取失败"
        return 1
    fi
}

# 提取所有库
extract_all_libraries() {
    local total=0
    local success=0
    local failed=0
    local failed_libs=()
    
    log_info "开始批量提取ABI..."
    log_info "库文件目录: $LIBRARY_DIR"
    
    # 遍历所有.so文件（去除符号链接，只处理实际文件）
    while IFS= read -r lib_file; do
        # 跳过符号链接
        if [ -L "$lib_file" ]; then
            continue
        fi
        
        ((total++))
        
        if extract_library_abi "$lib_file"; then
            ((success++))
        else
            ((failed++))
            failed_libs+=("$(basename "$lib_file")")
        fi
        
        echo ""
    done < <(find "$LIBRARY_DIR" -name "*.so*" -type f)
    
    # 输出摘要
    echo ""
    log_info "========================================"
    log_info "批量提取摘要"
    log_info "========================================"
    log_info "总计: $total 个库文件"
    log_success "成功: $success 个"
    
    if [ $failed -gt 0 ]; then
        log_error "失败: $failed 个"
        log_error "失败的库: ${failed_libs[*]}"
    fi
    
    log_info "输出目录: $OUTPUT_DIR"
    log_info "========================================"
    
    return $failed
}

# 生成索引文件
generate_index() {
    local index_file="$OUTPUT_DIR/index.json"
    
    log_info "生成索引文件..."
    
    # 创建索引JSON
    cat > "$index_file" << EOF
{
  "generated_at": "$(date -Iseconds)",
  "total_libraries": $(find "$OUTPUT_DIR" -name "*.abi.json" | wc -l | tr -d ' '),
  "libraries": [
EOF
    
    # 添加每个库的基本信息
    local first=true
    for json_file in "$OUTPUT_DIR"/*.abi.json; do
        if [ ! -f "$json_file" ]; then
            continue
        fi
        
        if [ "$first" = true ]; then
            first=false
        else
            echo "," >> "$index_file"
        fi
        
        local lib_name=$(basename "$json_file" .abi.json)
        local symbol_count=$(jq '.statistics.total_symbols' "$json_file" 2>/dev/null || echo 0)
        
        cat >> "$index_file" << EOFLIB
    {
      "name": "$lib_name",
      "abi_file": "$(basename "$json_file")",
      "symbol_count": $symbol_count
    }
EOFLIB
    done
    
    cat >> "$index_file" << EOF

  ]
}
EOF
    
    log_success "索引文件已生成: $index_file"
}

# 主流程
main() {
    log_info "========================================"
    log_info "OpenBMC ABI批量提取工具"
    log_info "========================================"
    
    # 检查工具
    check_tools
    
    # 准备输出目录
    prepare_output_dir
    
    # 提取所有库
    if extract_all_libraries; then
        log_success "所有库提取成功！"
    else
        log_error "部分库提取失败"
    fi
    
    # 生成索引
    generate_index
    
    log_success "========================================"
    log_success "ABI提取完成！"
    log_success "查看结果: ls -lh $OUTPUT_DIR"
    log_success "========================================"
}

# 执行主流程
main "$@"

